import axios from "axios";
import {
  getRsaKeys,
  rsaEncrypt,
  rsaDecrypt,
  aesDecrypt,
  aesEncrypt,
  get16RandomNum,
} from "./common";
import useUserStore from "@/store/modules/user";
import { ElMessage, ElMessageBox } from "element-plus";

let request = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API, //api
  timeout: 300000, //超时
  headers: {
    x_requested_with: "XMLHttpRequest",
  },
});

// 过期时间设置为一小时
const RSA_EXPIRATION_TIME = 60 * 60 * 1000; // milliseconds

let frontPrivateKey: string;

async function getOrUpdateRsaKeys() {
  const cachedKeys = sessionStorage.getItem("rsaKeys");
  if (cachedKeys) {
    const { privateKey, publicKey, timestamp } = JSON.parse(cachedKeys);
    // 检查是否过期
    if (Date.now() - timestamp < RSA_EXPIRATION_TIME) {
      return { privateKey, publicKey };
    }
  }
  // 缓存中不存在或者已过期，重新获取密钥对
  const { privateKey, publicKey } = await getRsaKeys();
  const newKeys = { privateKey, publicKey, timestamp: Date.now() };
  sessionStorage.setItem("rsaKeys", JSON.stringify(newKeys));
  return { privateKey, publicKey };
}

request.interceptors.request.use(
  async (config) => {
    let useStore = useUserStore();
    if (useStore.token) {
      // 判断是否存在token，如果存在的话，则每个http header都加上token
      config.headers["Authorization"] =
        `Bearer ${sessionStorage.getItem("X-Access-Token")}`;
    }
    if (config.headers["isEncrypt"]) {
      config.headers["Content-Type"] = "application/json;charset=utf-8";
      if (config.method === "post" || config.method === "put") {
        const { privateKey, publicKey } = await getOrUpdateRsaKeys();
        let afterPublicKey = sessionStorage.getItem("afterPublicKey");
        frontPrivateKey = privateKey;

        //每次请求生成aeskey
        let aesKey = get16RandomNum();
        //用登陆后 后端生成并返回给前端的的RSA密钥对的公钥 将 AES16位密钥进行加密
        let aesKeyByRsa = rsaEncrypt(aesKey, afterPublicKey as string);
        useStore.encryptedData = aesKeyByRsa;
        console.log(config.data, "data提交前");
        //使用AES16位的密钥将请求报文加密（使用的是加密前的aes密钥）
        if (config.data) {
          let data = aesEncrypt(aesKey, JSON.stringify(config.data));
          config.data = {
            data: data,
            aesKeyByRsa: aesKeyByRsa,
            frontPublicKey: publicKey,
          };
        }

        if (config.params) {
          let params = aesEncrypt(aesKey, JSON.stringify(config.params));
          config.params = {
            params: params,
            aesKeyByRsa: aesKeyByRsa,
            frontPublicKey: publicKey,
          };
        }
        config.headers["aesKeyByRsa"] = aesKeyByRsa;
      }
    }
    //config.url = "http://192.168.1.58:8820" + config.url;
    //config.url = "http://192.168.20.172:8820" + config.url;
    // config.url = "http://60.29.199.69:8820" + config.url;
    //config.url = "http://123.57.22.214:8820" + config.url;
    //config.url = "http://192.168.1.30:8820" + config.url;
    //config.url = "http://192.168.0.106:8820" + config.url;
    //config.url = "http://192.168.110.183:8820" + config.url;
    //config.url = "http://192.168.110.184:8820" + config.url;
    config.url = "http://192.168.110.63:8820" + config.url;
    //config.url = "http://192.168.110.163:8820" + config.url;
    //config.url = "http://localhost:8820" + config.url;
    //config.url = "http://192.168.110.228:8820" + config.url;
    // config.url = "http://127.0.0.1:8820" + config.url;

    return config;
  },
  (err) => {
    return Promise.reject(err);
  }
);

request.interceptors.response.use(
  (response) => {
    //console.log(response, "response");

    // 从响应数据中获取加密的 AES 密钥
    const aesKeyByRsa = response.data?.data?.aesKeyByRsa;
    // 响应数据为二进制流处理(Excel导出)
    if (response.data instanceof ArrayBuffer) {
      return response;
    }
    if (aesKeyByRsa) {
      // 使用 RSA 私钥解密 AES 密钥
      const aesKey = rsaDecrypt(aesKeyByRsa, frontPrivateKey);

      // 检查是否存在加密的数据
      if (response.data?.data?.data) {
        // 使用解密后的 AES 密钥解密数据
        const decryptedData = aesDecrypt(
          aesKey as any,
          response.data.data.data
        );
        // 将解密后的数据替换为解密后的内容
        response.data.data = JSON.parse(decryptedData);
      }
    }

    return response.data;
  },
  (error) => {
    //console.log(error, "error");
    // if (error.code === 'ECONNABORTED') {
    //     ElMessage.error('请求超时，请检查网络或稍后重试');
    //   } else {
    //     ElMessage.error(error.message || '导入失败');
    //   }
    let message = "";
    let status = error.response?.status;
    switch (status) {
      case 401:
        message = "TOKEN过期";

        break;
      case 403:
        message = "无权访问";
        break;
      case 404:
        message = "请求地址错误";
        break;
      case 500:
        message = "服务器出现问题";
        break;
      default:
        message = "网络出现问题";
    }
    if (error.response.data.code == 401) {
      ElMessageBox.confirm("当前页面已失效，请重新登录", "提示", {
        confirmButtonText: "确定",
        type: "warning",
      }).then(() => {
        let useStore = useUserStore();

        // router.push(
        //   `/login?returnUrl=${router.currentRoute.value.fullPath}`
        // );
        useStore.UserLogout();
        location.reload(); // 重新加载页面以确保路由生效
      });
    }

    if (message !== "TOKEN过期") {
      ElMessage({
        type: "error",
        message,
      });
    }

    return Promise.reject(error);
  }
);

export default request;
